using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace UnitTests
{
	public class NAntProject
	{
		private const string NAMESPACE = "http://nant.sf.net/nightly/2006-03-08-0.85/nant.xsd";
		private const string PREFIX = "x";
		private XmlDocument document;

		private XmlNode RootNode
		{
			get { return document.SelectSingleNode(string.Format("/{0}:project", PREFIX), GetNamespaceManager()); }
		}

		public NAntProject()
		{
			document = new XmlDocument();
			XmlNode rootNode = document.CreateElement("project", NAMESPACE);
			document.AppendChild(rootNode);
		}

		private XmlNamespaceManager GetNamespaceManager()
		{
			XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
			manager.AddNamespace(PREFIX, NAMESPACE);
			return manager;
		}

		public NAntProject(string fileName)
		{
			document = new XmlDocument();
			document.Load(fileName);
		}


		public NAntProject(string fileName, string name, string baseDir)
		{
			document = new XmlDocument();
			document.Load(fileName);
			Name = name;
			BaseDir = baseDir;
		}

		public string Name
		{
			get { return GetAttribute(RootNode, "name"); }
			set { SetAttribute(RootNode, "name", value); }
		}

		private string GetAttribute(XmlNode node, string name)
		{
			return node.Attributes[name] == null ? null : node.Attributes[name].Value;
		}

		private void SetAttribute(XmlNode node, string name, string val)
		{
			if (node.Attributes[name] == null)
			{
				XmlAttribute attribute = document.CreateAttribute(name);
				node.Attributes.Append(attribute);
			}
			node.Attributes[name].Value = val;
		}

		public string BaseDir
		{
			get { return GetAttribute(RootNode, "basedir"); }
			set { SetAttribute(RootNode, "basedir", value); }
		}

		public string DefaultTarget
		{
			get { return GetAttribute(RootNode, "default"); }
			set { SetAttribute(RootNode, "default", value); }
		}

		public void Write(string fileName)
		{
			using (XmlTextWriter writer = GetWriter(fileName))
				document.WriteTo(writer);
		}

		public string GetProperty(string propertyName)
		{
			XmlNode node = RootNode.SelectSingleNode(PropertyXPath(propertyName), GetNamespaceManager());
			if (null == node)
				return null;
			else
				return node.Attributes["value"].Value;
		}

		private static string PropertyXPath(string name)
		{
			return string.Format("{0}:property[@name='{1}']", PREFIX, name);
		}

		public void SetProperty(string name, string value)
		{
			XmlNode node = RootNode.SelectSingleNode(PropertyXPath(name), GetNamespaceManager());
			if (null==node)
			{
				XmlElement property = document.CreateElement("property", NAMESPACE);
				property.Attributes.Append(document.CreateAttribute("name"));
				property.Attributes.Append(document.CreateAttribute("value"));

				XmlNode insertBefore = RootNode.SelectSingleNode(PREFIX + ":property", GetNamespaceManager());
				if (null == insertBefore)
					RootNode.AppendChild(property);
				else
					RootNode.InsertBefore(property, insertBefore);

				node = property;
			}
			node.Attributes["name"].Value = name;
			node.Attributes["value"].Value = value;
		}

		private static XmlTextWriter GetWriter(string fileName)
		{
			XmlTextWriter writer = new XmlTextWriter(fileName, Encoding.Default);
			writer.Formatting = Formatting.Indented;
			return writer;
		}
	}
}